package com.zlq.cn.service.movie;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zlq.cn.bootstrap.SignApiBootstrap;
import com.zlq.cn.dto.param.MoviePageParam;
import com.zlq.cn.entity.Movie;
import com.zlq.cn.entity.MovieCategory;
import com.zlq.cn.entity.MovieComment;
import com.zlq.cn.entity.User;
import com.zlq.cn.mapper.movie.MovieMapper;
import com.zlq.cn.service.un.ConfigService;
import lombok.extern.slf4j.Slf4j;
import one.util.streamex.StreamEx;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 影片 服务实现类
 * </p>
 *
 * @author zhoucl
 * @since 2022-03-19
 */
@Slf4j
@Service
public class MovieService extends ServiceImpl<MovieMapper, Movie> {
    private static final String DOU_BAN_SEARCH = "https://www.douban.com/search?q=%s";
    private static final String DOU_BAN_COMMENTS = "https://movie.douban.com/subject/%s/comments?start=0&limit=100&status=P&sort=new_score";

    static {
        System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");
    }

    @Resource
    private MovieCategoryService movieCategoryService;

    @Resource
    private MovieCommentService movieCommentService;

    @Resource
    private ConfigService configService;

    public Page<Movie> page(MoviePageParam param) {
        if (param.getNoComment() == null) {
            param.setUserId(Optional.ofNullable(SignApiBootstrap.loginUser()).map(User::getId).orElse(null));
        }
        return baseMapper.selectMoviePage(param.getPage(), param);
    }

    public List<MovieCategory> listCategoryMovie() {
        List<MovieCategory> categories = movieCategoryService.lambdaQuery()
                .eq(MovieCategory::getStatus, 1).list();
        Map<Integer, List<Movie>> movieMap = baseMapper.selectMovie(categories).stream()
                .collect(Collectors.groupingBy(Movie::getMovieCategoryId));
        categories.forEach(movieCategory -> movieCategory.setMovies(movieMap.get(movieCategory.getMovieCategoryId())));
        return categories;
    }

    public void parseMovie() {
        String baseUrl = "https://www.zxzjhd.com/list/3-%s.html";
        System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        List<Movie> movies = new ArrayList<>();
        // 计算分页数，默认最多去3页
        int start = 2, maxPage = start + 20;
        for (int i = start; i < maxPage; i++) {
            // 加载当前分类页面
            driver.get(String.format(baseUrl, i));
            log.info("当前第：" + i + "页");
            // 每页视频信息
            List<WebElement> vodListEles = driver.findElements(By.cssSelector(".stui-vodlist__box"));
            for (WebElement vodListEle : vodListEles) {
                WebElement thumbElement = vodListEle.findElement(By.cssSelector(".stui-vodlist__thumb"));
                // 收集每个信息
                Movie movie = new Movie();
                String cover = thumbElement.getAttribute("data-original");
                if (!cover.startsWith("http")) {
                    continue;
                }
                movie.setCover(cover);
                movie.setName(vodListEle.findElement(By.cssSelector(".title a")).getText());
                movie.setNewStatus(thumbElement.findElement(By.cssSelector(".pic-text")).getText());
                movie.setStatus(1);
                movie.setMovieCategoryId(9);
                movie.setDetailPlayListUrl(thumbElement.getAttribute("href"));
                movies.add(movie);
            }
        }
        int count = 1;
        for (Movie movie : movies) {
            // 跳转视频播放列表
            String detailPlayListUrl = movie.getDetailPlayListUrl();
            driver.get(detailPlayListUrl);
            driver.findElement(By.cssSelector(".stui-content__detail .detail-more")).click();
            String desc = StreamEx.of(driver.findElements(By.cssSelector(".stui-content__detail .data")))
                    .map(WebElement::getText)
                    .append("简介：" + driver.findElement(By.cssSelector(".stui-content__detail .detail-content")).getText())
                    .joining("\n");
            movie.setDescription(desc);
            log.info("当前第：" + count + "个");
            count++;
        }
        super.saveBatch(movies);
        driver.quit();
    }

    public void parseComment() {
        System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");
        MoviePageParam param = new MoviePageParam();
        param.setMovieCategoryId(9);
        param.setSize(10000L);
        param.setCurrent(1L);
        param.setNoComment("1");
        Page<Movie> page = page(param);
        List<Movie> records = page.getRecords();
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            WebDriver driver = new ChromeDriver();
            driver.manage().window().maximize();
            driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
            JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
            for (Movie movie : records) {
                try {
                    driver.get(String.format(DOU_BAN_SEARCH, movie.getName()));
                    driver.get(driver.findElement(By.cssSelector(".result-list .result a")).getAttribute("href"));
                    String url = driver.getCurrentUrl();
                    url = url.substring(0, url.lastIndexOf("/"));
                    url = url.substring(url.lastIndexOf("/") + 1);
                    driver.get(String.format(DOU_BAN_COMMENTS, url));
                    StreamEx.of(driver.findElements(By.cssSelector("#comments .comment-item")))
                            .map(element -> {
                                WebElement avatarEle = element.findElement(By.cssSelector(".avatar a"));
                                String rating = null;
                                try {
                                    rating = element.findElement(By.cssSelector(".rating")).getAttribute("class").split(" ")[0].replace("allstar", "");
                                } catch (Exception e) {
                                    System.out.println("这个叼毛没有评分==》" + avatarEle.getAttribute("title"));
                                }
                                return new MovieComment()
                                        .setAvatarName(avatarEle.getAttribute("title"))
                                        .setAvatarHead(avatarEle.findElement(By.cssSelector("img")).getAttribute("src"))
                                        .setRating(rating)
                                        .setTime(LocalDateTimeUtil.parse(element.findElement(By.cssSelector(".comment-time")).getAttribute("title"), "yyyy-MM-dd HH:mm:ss"))
                                        .setContent(element.findElement(By.cssSelector(".short")).getText())
                                        .setMovieId(movie.getMovieId())
                                        .setStatus(1);
                            })
                            .toListAndThen(movieCommentService::saveBatch);
                } catch (Exception e) {
                    log.error("", e);
                }
            }
            driver.quit();
        }
    }

    public void convertCover() {
        String baseUrl = "https://thirtyfairy.oss-cn-shenzhen.aliyuncs.com/";
        List<Movie> movies = super.lambdaQuery().apply(" cover not like '"+baseUrl+"%' ").list();
        if (CollectionUtils.isNotEmpty(movies)) {
            StreamEx.of(movies)
                    .parallel(new ForkJoinPool(3))
                    .forEach(movie -> {
                        log.error("开始处理==>" + movie.getCover());
                        try (HttpResponse httpResponse = HttpUtil.createGet(movie.getCover()).execute()) {
                            String newCover = baseUrl + configService.putObject("movie/cover", movie.getCover(), null, httpResponse.bodyBytes());
                            movie.setOriginalCover(movie.getCover());
                            movie.setCover(newCover);
                            log.error("处理成功，新连接==>" + newCover);
                            super.updateById(movie);
                        } catch (Exception e) {
                            log.error("convertCover", e);
                            log.info(JSON.toJSONString(movie));
                        }
                    });
        }
    }
}
